﻿using System;

namespace DotNetImage.Imaging.Filters
{
    public class GammaFilter : FilterBase
    {
        private uint[] redGamma = new uint[256];
        private uint[] greenGamma = new uint[256];
        private uint[] blueGamma = new uint[256];

        [ParameterAttribute(Name="Red", DefaultValue=1, MinValue=0.2, MaxValue=5, Step=0.1)]
        public double Red { get; set; }

        [ParameterAttribute(Name = "Green", DefaultValue = 1, MinValue = 0.2, MaxValue = 5, Step = 0.1)]
        public double Green { get; set; }

        [ParameterAttribute(Name = "Blue", DefaultValue = 1, MinValue = 0.2, MaxValue = 5, Step = 0.1)]
        public double Blue { get; set; }


        protected override void ValidateArguments()
        {
            Validator.ValidateInclusiveRange("Red", Red, 0.2, 5);
            Validator.ValidateInclusiveRange("Green", Red, 0.2, 5);
            Validator.ValidateInclusiveRange("Blue", Red, 0.2, 5);
        }

        protected override void PrepareData(DotNetImage bmp)
        {
            base.PrepareData(bmp);

            // Prepare initial values depending on parameters
            for (int i = 0; i < 256; ++i)
            {
                redGamma[i] = (uint)Math.Min(255, (int)((255.0 * Math.Pow(i / 255.0, 1.0 / Red)) + 0.5));
                greenGamma[i] = (uint)Math.Min(255, (int)((255.0 * Math.Pow(i / 255.0, 1.0 / Green)) + 0.5));
                blueGamma[i] = (uint)Math.Min(255, (int)((255.0 * Math.Pow(i / 255.0, 1.0 / Blue)) + 0.5));
            }
        }

        protected override void ProcessPixel(ref Pixel pix, uint x, uint y)
        {
            pix.Blue = blueGamma[pix.Blue];
            pix.Green = greenGamma[pix.Green];
            pix.Red = redGamma[pix.Red];
        }
    }
}
